{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "自定义层\n",
    "custom"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mxnet import gluon, nd\n",
    "from mxnet.gluon import nn\n",
    "\n",
    "class CenteredLayer(nn.Block):\n",
    "    def __init__(self, **kwargs):\n",
    "        super(CenteredLayer, self).__init__(**kwargs)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        return x - x.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       "[-2. -1.  0.  1.  2.]\n",
       "<NDArray 5 @cpu(0)>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "layer = CenteredLayer()\n",
    "layer(nd.array([1, 2, 3, 4, 5]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "net = nn.Sequential()\n",
    "net.add(nn.Dense(128),\n",
    "       CenteredLayer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-6.0936145e-10"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net.initialize()\n",
    "y = net(nd.random.uniform(shape=(4, 8)))\n",
    "y.mean().asscalar()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(\n",
       "  Parameter param2 (shape=(2, 3), dtype=<class 'numpy.float32'>)\n",
       ")"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "params = gluon.ParameterDict()\n",
    "params.get('param2', shape=(2, 3))\n",
    "params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "class MyDense(nn.Block):\n",
    "    def __init__(self, units, in_units, **kwargs):\n",
    "        super(MyDense, self).__init__(**kwargs)\n",
    "        self.weight = self.params.get('weight', shape=(in_units, units))\n",
    "        self.bias = self.params.get('bias', shape=(units,))\n",
    "        \n",
    "    def forward(self, x):\n",
    "        linear = nd.dot(x, self.weight.data()) + self.bias.data()\n",
    "        return nd.relu(linear)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "mydense2_ (\n",
       "  Parameter mydense2_weight (shape=(5, 3), dtype=<class 'numpy.float32'>)\n",
       "  Parameter mydense2_bias (shape=(3,), dtype=<class 'numpy.float32'>)\n",
       ")"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dense = MyDense(units=3, in_units=5)\n",
    "dense.params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       "[[0.06917784 0.01627153 0.01029644]\n",
       " [0.02602214 0.04537309 0.        ]]\n",
       "<NDArray 2x3 @cpu(0)>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dense.initialize()\n",
    "dense(nd.random.uniform(shape=(2, 5)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       "[[0.03820475]\n",
       " [0.04035058]]\n",
       "<NDArray 2x1 @cpu(0)>"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net = nn.Sequential()\n",
    "net.add(MyDense(8, in_units=64),\n",
    "       MyDense(1, in_units=8))\n",
    "net.initialize()\n",
    "net(nd.random.uniform(shape=(2, 64)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\n",
       "[[0.         0.02280167 0.         0.04409103]\n",
       " [0.         0.00430965 0.         0.03510828]\n",
       " [0.01843599 0.01175718 0.         0.02947279]\n",
       " [0.         0.01619794 0.         0.02685324]]\n",
       "<NDArray 4x4 @cpu(0)>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net = nn.Sequential()\n",
    "net.add(MyDense(10, in_units=100),\n",
    "      MyDense(4, in_units=10))\n",
    "net.initialize()\n",
    "net(nd.random.uniform(shape=(4, 100)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
